<?php
/**
 * Classe per la gestione dei Form.
 *
 * @author Damiano Ciarla
 */
class Form
{
	const SIZE			= 25;
	const MAXLENGTH		= 255;
	const NUM_ROWS		= 10;
	const ROWS			= 3;
	const COLS			= 40;
	const DEFAULT_STYLE	= "default";

	//--> Variabili di base per la gestione dei Form

	private $name		= NULL;
	private $action		= NULL;
	private $method		= "post";
	private $target		= "_self";

	private $isAjax				= FALSE;	//--> Variabile che decide se il form avra' un submit in Ajax o meno
	private $callbackFunction	= NULL;		//--> Chiamata Javascript di callback
	private $nameDialogBox 		= NULL;		//--> Nome di una eventuale Dialog che conterra' il form

	//--> Variabili di personalizzazione

	private $styleForm			= NULL;
	private $classErrorList		= NULL;
	private $showError			= TRUE;
	private $showCustomError	= FALSE;
	private $showCustomButton	= FALSE;
	protected $configuration	= array();

	private $submit	= NULL;
	private $reset	= NULL;

	/**
	 * Inizializzazione della classe Form. Impostazione dei parametri base per la creazione di un nuovo Form
	 *
	 * @param string $name				Nome del Form
	 * @param string $action			Action del Form > Pagina di destinazione della richiesta
	 * @param boolean $isAjax			Parametro che imposta se il form e' AJAX o meno indipendentemente se '$callbackFunction' e '$nameDialogBox' sono valorizzati o meno
	 * @param string $callbackFunction	Chiamata Javascript al termine della richiesta. Trasforma il Form in un form AJAX
	 * @param string $nameDialogBox		Nome della Dialog da chiudere alla fine della richiesta AJAX
	 * @param string $classErrorList	Classe degli errori generata dal Form Validator
	 */

	public function __construct($name, $action, $isAjax = false, $callbackFunction = null, $nameDialogBox = null, $classErrorList = null)
	{
		$this->name 	= $name;
		$this->action 	= $action;

		$this->submit	= TD_("Salva", "label");
		$this->reset	= TD_("Reset", "label");

		if(is_bool($isAjax))
			$this->isAjax = $isAjax;	//--> Setto se il form dovra' essere inviato tramite AJAX

		if(is_null($callbackFunction) || is_string($callbackFunction))
			$this->callbackFunction = $callbackFunction;	//--> Setta se il form deve effettuare una chiamata Javascript al termine dell'invio

		if(is_null($nameDialogBox) || is_string($nameDialogBox))
			$this->nameDialogBox = $nameDialogBox;			//--> Imposta quale finestra dovra' essere chiusa se il form si trova in una Dialog

		if(is_null($classErrorList) || is_string($classErrorList))
			$this->classErrorList = $classErrorList;		//--> Setta la classe degli errori generata dal Form Validator
	}

	//--> METODI PER MODIFICARE LE IMPOSTAZIONI DI DEFAULT

	/**
	 * Imposta con quale metodo dovra' essere inviato il form
	 *
	 * @param string $method Metodo per l'invio del Form
	 */

	public function setMethod($method)
	{
		if(is_string($method) && ($method == "post" || $method == "get")) $this->method = $method;
	}

	/**
	 * Setta il target del FORM quando questo non e' impostato per inviare dati in AJAX
	 *
	 * @param string $target Target del Form
	 */

	public function setTarget($target)
	{
		if(is_string($target) && ($target == "_self" || $target == "_blank" || $target == "_parent")) $this->target = $target;
	}

	/**
	 * Metodo per impostare se il form deve avere un submit in AJAX
	 *
	 * @param boolean $isAjax Imposta se il form deve essere inviato tramite AJAX
	 */

	public function setIsAjax($isAjax)
	{
		if(is_bool($isAjax)) $this->isAjax = $isAjax;
	}

	/**
	 * Metodo per impostare se visualizzare a video o meno i messaggi di errore del form
	 *
	 * @param boolean $showError Imposta se i messaggi di errore devono essere visualizzati
	 */

	public function setShowError($showError)
	{
		if(is_bool($showError)) $this->showError = $showError;
	}

	/**
	 * Metodo per impostare se visualizzare i messaggi di errore in una locazione
	 * personalizzata, diversa da quella di default. Se viene impostato il valore
	 * TRUE per mostrare a video i messaggi di errore bisognera' utilizzare il
	 * metodo 'showCustomError()'
	 *
	 * @param boolean $showCustomError TRUE o FALSE
	 */

	public function setShowCustomError($showCustomError)
	{
		if(is_bool($showCustomError)) $this->showCustomError = $showCustomError;
	}

	/**
	 * Metodo che usato insieme a 'setShowCustomError($showCustomError)' permette di
	 * visualizzare i messaggi di errore in una posizione diversa da quella di default
	 */

	public function showCustomError()
	{
		echo '<div id="errorForm' . ucfirst($this->name) . '" class="listErrorForm">';
		if(!$this->isAjax && is_null($this->callbackFunction))
			Error::getInstance()->showErrorList($this->classErrorList);
		echo '</div>';
	}

	/**
	 * Metodo per impostare se visualizzare i pulsanti di SUBMIT e RESET in una posizione
	 * personalizzata diversa da quella di default. Se impostato su TRUE il valore in
	 * ingresso la visualizzazione di tali pulsanti dipende dai metodi 'showCustomButtonReset()' e
	 * 'showCustomButtonSubmit()'
	 *
	 * @param boolean $showCustomButton TRUE o FALSE
	 */

	public function setShowCustomButton($showCustomButton)
	{
		if(is_bool($showCustomButton)) $this->showCustomButton = $showCustomButton;
	}

	public function showCustomButtonReset()
	{
		if(!is_null($this->reset))
			echo '<button type="reset" class="buttonForm">' . $this->reset . '</button>';
	}

	public function showCustomButtonSubmit()
	{
		if(!is_null($this->submit))
			echo '<button type="submit" class="buttonForm">' . $this->submit . '</button>';
	}

	/**
	 * Metodo che imposta la chimata che deve fare il Form al termine della richiesta AJAX.
	 * Impostando questo parametro il form viene automaticamente trasformato in un form con richiesta AJAX
	 *
	 * @param string $callbackFunction Nome della funziona da chiamare al termine della richiesta AJAX
	 */

	public function setCallbackFunction($callbackFunction)
	{
		if(is_null($callbackFunction) || is_string($callbackFunction)) $this->callbackFunction = $callbackFunction;
	}

	/**
	 * Metodo per impostare il nome di una eventuale Dialog Box he dovra' esssere chiusa al termine della richiesta AJAX
	 * Impostando questo parametro il form viene automaticamente trasformato in un form con richiesta AJAX
	 *
	 * @param string $nameDialogBox Nome della Dialog Box che dovra' essere chiusa
	 */

	public function setNameDialogBox($nameDialogBox)
	{
		if(is_null($nameDialogBox) || is_string($nameDialogBox)) $this->nameDialogBox = $nameDialogBox;
	}

	/**
	 * Metodo che imposta il nome della classe CSS per lo stile grafico del Form
	 *
	 * @param string $name				Nome della classe per il form
	 */

	public function setStyleForm($name)
	{
		$this->styleForm = $name;
	}

	/**
	 * Metodo per settare la il nome della classe per la stampa degli errori. Facendo riferimento alla classe
	 * 'ERROR' il parametro che viene settato all'interno di quest'ultima e' 'referer'.
	 *
	 * Questo metodo e' utile quando si hanno piu' form in una stessa pagine e si vogliono separare i messaggi
	 * di errore l'uno dall'altro
	 *
	 * Si ricorda che per avere effetto bisogna impostare nel CONTROLLER che esegue la validazione lo stesso
	 * nome esplicitato nel seguente metodo
	 *
	 * @param string $classErrorList Nome della classe per la stampa degli errori
	 */

	public function setClassErrorList($classErrorList)
	{
		if(is_null($classErrorList) || is_string($classErrorList)) $this->classErrorList = $classErrorList;
	}

	/**
	 * Metodo che imposta il nome del progetto dove la seguente classe deve andare a cercare i componenti
	 * creati per estendere quelli presenti di default
	 *
	 * @param string $project Nome del progetto
	 */

	public function setCustomProject($project)
	{
		if(is_string($project)) $this->customProject = $project;
	}

	/**
	 * Metodo che imposta la cartella dove sono contenuti i nuovi componenti dell CLASSE che estende la seguente
	 * Di default il valore di questa cartella e' impostato come 'form'
	 *
	 * @param string $folder Nome della cartella dove cercare i nuovi componenti
	 */

	public function setCustomFolder($folder)
	{
		if(is_string($folder)) $this->customFolder = $folder;
	}

	//--> METODI PER LA CONFIGURAZIONE DEL FORM

	public function text($label, $name, $value = "", $size = self::SIZE, $MAXLENGTH = self::MAXLENGTH, $id = null)
	{
		$this->configuration[] = array("TYPE"=>"text", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "VALUE"=>$value, "SIZE"=>$size, "MAXLENGTH"=>$MAXLENGTH, "ID"=>$id));
	}

	public function textarea($label, $name, $value = "", $rows = self::ROWS, $cols = self::COLS, $id = null)
	{
		$this->configuration[] = array("TYPE"=>"textarea", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "VALUE"=>$value, "ROWS"=>$rows, "COLS"=>$cols, "ID"=>$id));
	}

	public function password($label, $name, $value = "", $size = self::SIZE, $MAXLENGTH = self::MAXLENGTH, $id = null)
	{
		$this->configuration[] = array("TYPE"=>"password", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "VALUE"=>$value, "SIZE"=>$size, "MAXLENGTH"=>$MAXLENGTH, "ID"=>$id));
	}

	public function hidden($name, $value, $id = null)
	{
		$this->configuration[] = array("TYPE"=>"hidden", "PARAM"=>array("NAME"=>$name, "VALUE"=>$value, "ID"=>$id));
	}

	public function date($label, $name, $value = "", $size = self::SIZE, $MAXLENGTH = self::MAXLENGTH, $id = null, $hiddenButton = FALSE, $format = "yy-mm-dd", $imgCal = "/img/template/ico_calendar.png")
	{
		$this->configuration[] = array("TYPE"=>"date", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "VALUE"=>$value, "SIZE"=>$size, "MAXLENGTH"=>$MAXLENGTH, "ID"=>$id, "HIDDEN_BUTTON"=>$hiddenButton, "FORMAT"=>$format, "IMG_CAL"=>$imgCal));
	}

	public function sex($label, $name, $default = "", $id = null, $labelM = "Uomo", $labelF = "Donna")
	{
		$this->configuration[] = array("TYPE"=>"sex", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "DEFAULT"=>$default, "ID"=>$id, "LABEL_M"=>$labelM, "LABEL_F"=>$labelF));
	}

	public function select($label, $name, $values, $default = "", $id = null, $emptyVal = "", $emptyMessage = "Nessun valore presente")
	{
		$this->configuration[] = array("TYPE"=>"select", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "VALUES"=>$values, "DEFAULT"=>$default, "ID"=>$id, "EMPTY_VAL"=>$emptyVal, "EMPTY_MESSAGE"=>$emptyMessage));
	}

	public function checkbox($label, $name, $values, $default = "", $emptyVal = "", $emptyMessage = "Nessun valore presente")
	{
		$this->configuration[] = array("TYPE"=>"checkbox", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "VALUES"=>$values, "DEFAULT"=>$default, "EMPTY_VAL"=>$emptyVal, "EMPTY_MESSAGE"=>$emptyMessage));
	}

	public function radio($label, $name, $values, $default = "", $emptyVal = "", $emptyMessage = "Nessun valore presente")
	{
		$this->configuration[] = array("TYPE"=>"radio", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "VALUES"=>$values, "DEFAULT"=>$default, "EMPTY_VAL"=>$emptyVal, "EMPTY_MESSAGE"=>$emptyMessage));
	}

	public function editorText($label, $name, $id, $numRows = self::NUM_ROWS, $value = "")
	{
		$this->configuration[] = array("TYPE"=>"editor_TEXT", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "ID"=>$id, "NUM_ROWS"=>$numRows, "VALUE"=>$value));
	}

	public function editorFull($label, $name, $id, $numRows = self::NUM_ROWS, $value = "")
	{
		$this->configuration[] = array("TYPE"=>"editor_FULL", "PARAM"=>array("LABEL"=>$label, "NAME"=>$name, "ID"=>$id, "NUM_ROWS"=>$numRows, "VALUE"=>$value));
	}

	//--> FINE METODI CONFIGURAZIONE DEL FORM

	/**
	 * Metodo per la stampa del Form.
	 * Questa funzione prende l'array 'configuration' e ne elabora i valori includendo, a seconda del tipo di input
	 * che si intendo visualizzare, il relativo file .php presente nella cartella 'components/tools/form/modules' in modo
	 * tale da poter visualizzare a video il Form finale.
	 */

	public function show($jsonResponse = FALSE)
	{
		if (is_null($this->callbackFunction) && is_null($this->nameDialogBox) && !$this->isAjax)
		{
			$this->showField("start_classic", array("NAME"=>$this->name, "ACTION"=>$this->action, "METHOD"=>$this->method, "TARGET"=>$this->target));
		}
		else
		{
			if(!$jsonResponse)
				$this->showField("start", array("NAME"=>$this->name, "ACTION"=>$this->action, "METHOD"=>$this->method, "CALLBACK_FUNCTION"=>$this->callbackFunction, "DIALOG_BOX"=>$this->nameDialogBox));
			else
				$this->showField("startJson", array("NAME"=>$this->name, "ACTION"=>$this->action, "METHOD"=>$this->method, "CALLBACK_FUNCTION"=>$this->callbackFunction, "DIALOG_BOX"=>$this->nameDialogBox));
		}

		foreach ($this->configuration as $input)
			$this->showField($input['TYPE'], $input['PARAM']);

		$this->showField("end", array("SUBMIT"=>$this->submit, "RESET"=>$this->reset, "CUSTOM_BUTTON"=>$this->showCustomButton));
	}

	//--> IMPOSTAZIONI PER I PULSANTI 'SUBMIT' E 'RESET'

	public function setSubmit($submit)
	{
		if(is_null($submit) || is_string($submit)) $this->submit = $submit;
	}

	public function setReset($reset)
	{
		if(is_null($reset) || is_string($reset)) $this->reset = $reset;
	}

	/*** -------------------- *** METODI INTERNI *** -------------------- ***/

	private function showField($type, $param)
	{
		if(file_exists(BXD_INCLUDEPATH . 'components/tools/form/modules/' . $type . '.php'))
			include BXD_INCLUDEPATH . 'components/tools/form/modules/' . $type . '.php';
		else
			if(file_exists('../include/form/' . $type . '.php'))
				include '../include/form/' . $type . '.php';
	}
}
?>